package gcp.testes;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import gcp.Usuario;
import gcp.cadastros.CadastroUsuario;
import gcp.enums.Sexo;

import org.junit.Before;
import org.junit.Test;

/**
 * Classe de teste do CadastroUsuario.
 */
public class CadastroUsuarioTeste {

    private CadastroUsuario banc1;
    private Usuario user1;
    private Usuario user2;
    private Usuario user3;

    /**
     * Criacao das variaveis.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Before
    public void inicializa() throws Exception {
        banc1 = new CadastroUsuario();
        user1 = new Usuario("Hildegard", "Furtado", Sexo.FEMININO,
                "hildegardfurtado", "1234567");
        user2 = new Usuario("Girafa", "Amarela", Sexo.MASCULINO,
                "girafaamarela", "1234567");
        user3 = new Usuario("Girafo", "Amarelo", Sexo.MASCULINO,
                "girafoamarelo", "1234568");
        banc1.addUsuario(user2);
    }

    /**
     * Testa adicionar usuarios.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test
    public void testaAddUsuario() throws Exception {
        assertEquals("testaAddUsuario 1", 1, banc1.getNumeroDeUsuarios());
        banc1.addUsuario(user1);
        assertEquals("testaAddUsuario 2", 2, banc1.getNumeroDeUsuarios());
    }

    /**
     * Testa adicionar um usuario nulo.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test(expected = Exception.class)
    public void testaUsuarioNulo() throws Exception {
        banc1.addUsuario(null);
    }

    /**
     * Testa o metodo get.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test
    public void testaGet() throws Exception {
        banc1.addUsuario(user1);
        assertEquals("testaGet", user1, banc1.get("hildegardfurtado"));
        assertEquals("testaGet", user2, banc1.get("girafaamarela"));
        assertEquals("testaGet", null, banc1.get("xxxx"));
    }

    /**
     * Testa remover usuarios.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test
    public void testaRemoveUsuario() throws Exception {
        assertEquals("testaRemoveUsuario 0", user2, banc1.get("girafaamarela"));
        assertEquals("testaRemoveUsuario 1", 1, banc1.getNumeroDeUsuarios());
        banc1.removerUsuario("girafaamarela");
        assertEquals("testaRemoveUsuario 2", 0, banc1.getNumeroDeUsuarios());
        assertEquals("testaRemoveUsuario 3", null, banc1.get("girafaamarela"));
    }

    /**
     * Testa remover usuario nulo.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test(expected = Exception.class)
    public void testaRemoveUsuarioLoginNulo() throws Exception {
        banc1.removerUsuario(null);
    }

    /**
     * Testa remover usuario inexitente.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test(expected = Exception.class)
    public void testaRemoveUsuarioInexistente() throws Exception {
        banc1.removerUsuario("jacare");
    }

    /**
     * Testa a autenticacao do usuario.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test
    public void testaAutentificarUsuario() throws Exception {
        banc1.addUsuario(user1);
        banc1.autenticarUsuario("hildegardfurtado", "1234567");
        assertEquals("testaAutenticaUsuario 1", "hildegardfurtado", user1
                .getLogin());
        assertEquals("testaAutenticaUsuario 2", "1234567", user1.getSenha());
        assertEquals("testeAutenticaUsuario 3", "1234567", user2.getSenha());
    }

    /**
     * Testa a autenticacao de um usuario inexistente.
     * @throws Exception Lancada quando algum parametro for nulo.
     */
    @Test(expected = Exception.class)
    public void testaAutentificarUsuarioInexistente() throws Exception {
        banc1.autenticarUsuario("cccc", "dsds");
    }

    /**
     * Testa os usuarios existentes na lista de Usuarios.
     * @throws Exception
     */
    @Test
    public void testaGetUsuarios() throws Exception {
        banc1.addUsuario(user1);
        assertTrue(banc1.getUsuarios().contains(user1));
        assertTrue(banc1.getUsuarios().contains(user2));
        assertFalse(banc1.getUsuarios().contains(user3));
        banc1.addUsuario(user3);
        banc1.removerUsuario(user1.getLogin());
        assertFalse(banc1.getUsuarios().contains(user1));
        assertTrue(banc1.getUsuarios().contains(user3));
        banc1.removerUsuario(user2.getLogin());
        banc1.removerUsuario(user3.getLogin());
        assertFalse(banc1.getUsuarios().contains(user3));
        assertFalse(banc1.getUsuarios().contains(user2));
    }
    
    /**
     * Testa o metodo getMapa.
     * @throws Exception 
     */
	@Test
    public void testaGetMapa() throws Exception {	    
	    assertFalse(banc1.getUsuarios().contains(user1));
	    assertTrue(banc1.getUsuarios().contains(user2));
    	assertFalse(banc1.getUsuarios().contains(user3));
    	
	    banc1.addUsuario(user1);
	    banc1.addUsuario(user3);
	    
	    assertTrue(banc1.getUsuarios().contains(user1));
	    assertTrue(banc1.getUsuarios().contains(user2));
    	assertTrue(banc1.getUsuarios().contains(user3));
    	
      	banc1.removerUsuario(user2.getLogin());
    	
    	assertFalse(banc1.getUsuarios().contains(user2));
    }
	
	/**
	 * Testa o método setMapa.
	 */
	@Test
    public void testaSetMapa() {
		List<Usuario> lista = new ArrayList<Usuario>();
		
		lista.add(user2);
		lista.add(user3);
		banc1.setUsuarios(lista); 
		
		assertTrue(banc1.getUsuarios().contains(user2));
    	assertTrue(banc1.getUsuarios().contains(user3));
    	
    	lista.add(user1);
    	banc1.setUsuarios(lista);
		
    	assertTrue(banc1.getUsuarios().contains(user1));
	    assertTrue(banc1.getUsuarios().contains(user2));
    	assertTrue(banc1.getUsuarios().contains(user3));
	}
}